-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make target_desired_distance
affect the navigation of NavigationAgent2D/3D
#82561
Make target_desired_distance
affect the navigation of NavigationAgent2D/3D
#82561
Conversation
This is unrelated to the PR but I have some questions about the implementation of NavigationAgents.
|
I think what should change is to make sure that the Users can set a @ershn |
Yes, that's a reasonable fix. But aren't there genuine use cases where you would want the agent to loosely follow the path but still end up close to the target ? I honestly don't need that in my project right now but that doesn't seem to be an unreasonable requirement.
Sure ! I didn't know about that chat. I'll ask my questions there then. Thank you ! |
Yes there could. To support this the pathfollowing would need to be changed so that it does not reset immediately on the last path array point. So this would need to change the check in a way similar like you already outlined. E.g. use the target_desired_distance if feasible but use the path_desired_distance still if the target is not right or reachable. |
Ok, I'll update the PR to do that then. |
da6ba59
to
e80b7f9
Compare
I updated the PR to implement the behavior as described in a previous comment.
Please note that this will slightly change the timing at which the Additional notes:
Also, I'm not sure if we still need to call |
e80b7f9
to
f85835a
Compare
I pushed a small fix to the class reference. I was confusing |
Thinking about the problem again, I think the fix in its current form would lead to surprising behavior in some specific cases. Until now, Also, in case The diagram below shows how the navigation agent behaves currently.
Below is how the behavior would change with this fix. Conceptually the current fix would make it so that @smix8 I think now that we should just make it so that the target distance check runs until necessary, i.e. when the target is reachable, keep running the target distance check on For reference, the diagram below illustrates the problem I'm trying to fix with this PR. As you can see there is no blue dot. The |
I think it would be. The |
I see ! If that's the intended effect of Before making changes, I'd like your opinion on the following scenario. What do you think should happen here ? If we end the navigation when the blue circle is reached, the last returned waypoint will actually be outside of the target's radius. But maybe there isn't much we can do here ? (and we should let the user be responsible for stopping the movement when the target is reached ?) |
For that to happen users would need to set the |
I agree that users are responsible for the settings they use and that common cases should be prioritized. We seem to agree that there is no problem here, so I'll proceed with the changes 👍 |
f85835a
to
010f1be
Compare
} | ||
|
||
emit_signal(SNAME("navigation_finished")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The diff doesn't make it clear but _trigger_waypoint_reached
and _transition_to_navigation_finished
only contain code that was previously in update_navigation
. The processing itself is unchanged.
@@ -274,7 +274,6 @@ void NavigationAgent2D::_notification(int p_what) { | |||
NavigationServer2D::get_singleton()->agent_set_velocity_forced(agent, velocity_forced); | |||
} | |||
} | |||
_check_distance_to_target(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since reaching the target now ends the navigation, it's not enough anymore to just try to update target_reached
and emit the corresponding signal on each frame. We need to also update the navigation state and I think this should be left to _update_navigation
.
@@ -180,7 +180,7 @@ | |||
The distance to search for other agents. | |||
</member> | |||
<member name="path_desired_distance" type="float" setter="set_path_desired_distance" getter="get_path_desired_distance" default="20.0"> | |||
The distance threshold before a path point is considered to be reached. This allows agents to not have to hit a path point on the path exactly, but only to reach its general area. If this value is set too high, the NavigationAgent will skip points on the path, which can lead to leaving the navigation mesh. If this value is set too low, the NavigationAgent will be stuck in a repath loop because it will constantly overshoot or undershoot the distance to the next point on each physics frame update. | |||
The distance threshold before a path point is considered to be reached. This allows agents to not have to hit a path point on the path exactly, but only to reach its general area. If this value is set too high, the NavigationAgent will skip points on the path, which can lead to it leaving the navigation mesh. If this value is set too low, the NavigationAgent will be stuck in a repath loop because it will constantly overshoot the distance to the next point on each physics frame update. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I understand undershooting is not a problem because the agent will simply move a little bit closer to the waypoint each frame.
This proved to be more work than I expected but the PR should be ready for review now. |
target_desired_distance
affect the navigation of NavigationAgent2D/3D
I originally thought navigation should finish once the destination waypoint is reached:
I like this implementation though, since it allows you to preempt the pathfinding if you get within target_desired_distance (if that is greater than path_desired_distance) - possibly allowing an agent to (maybe only incidentally) avoid pathing around a wall if unnecessary. I'm fine with this fix because it solves my particular problem - I don't want my agents to be picky about hitting their path waypoints, but I want them to stop almost exactly where they're told (target_desired_distance < path_desired_distance). The 4.1 implementation doesn't take this difference into account, and I'm excited to see this change. |
010f1be
to
526b7b8
Compare
Rebased and re-tested. |
I tested it for the discussed changes and it works in general fine for the target desired distance as I would expect but what worked unexpectedly is that target desired distance seem to not reliably or at all overrule the path desired distance for the last path position.
E.g. if I set a NavigationAgent |
@smix8 I can't reproduce the problem you're seeing on my side. Could you provide a test project to reproduce the behavior you are seeing ? Or maybe the source code you are using for the agent ?
The only reason I can see this happening is because the target is unreachable. If the target is unreachable the Or maybe it's because you are requesting a new path directly when reaching the last waypoint ? E.g. even after this change and even if The test project I uploaded in the description tests for the scenario you are describing but everything seems to be working as expected. In the images below, the white cross/cylinder is also the final position of the agent. |
I tested the 2D scene and it works as expected. I tested the 3D scene with path_desired_distance = 2.0 and target_desired_distance = 0.1. The agent stops at the path desired distance circle. I noticed that the problem happens with any target desired distance value below 0.5 in that scene. I had the same low distance values in my own test project so I ran in that same issue. |
526b7b8
to
c8f4819
Compare
Ah I see ! In that scene On an unrelated note, I took this opportunity to also change the order in which the |
I tested the change with the 3D demo scene but with any target_desired_distance below 0.5 is enough to get the agent stuck on the last path_desired_distance red circle instead of moving closer to the target_desired_distance blue circle. |
Sorry but I really can't reproduce the problem this time. Could you provide more info ? I did a fresh build on this branch, downloaded the zip in the description, and run every 3D scene with values of It also doesn't seem like I forgot to push a commit. Please note that you need to have a |
It is fine and works. I noticed I made a mistake. I set some properties in script from testing. When I started to print those values I noticed that they did not match what I set on the NavigationAgent node. |
…2D/3D When the target is reachable, stop the navigation only when the target is reached.
c8f4819
to
fce16b6
Compare
When can we hope a release ? I think I'm affected by this bug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me! Documentation changes alone are very much appreciated, and improved logic and code organization are just a cherry on top 🙂
Thanks! |
I am trying to create an agent that utilizes Path Desired Distance with .1 and Target Desired Distance with .1 but it just seems to get stuck in a re-loop 99.99% of the time, the goal is to have 99.99% precision in my case . Hopefully this fixes that issue if I understand this thread correctly. I have not tested or reviewed the code being implemented here. |
Any news ? For the moment I still use a hack to avoid actor bouncing around the final destination (Godot 4.3-stable) :
|
Make
target_desired_distance
affect the navigation ofNavigationAgent2D/3D
.I created a test project to compare the old and new behavior.
Navigation agent tests.zip
Below are screenshots of running the test scenes on 4.1 and this branch.
Test scene screenshots
NavigationAgent2D
4.1
This branch
NavigationAgent3D
Legend
waypoint_reached
signal was emittedtarget_reached
signal was emittednavigation_finished
signal was emitted4.1
This branch
Notes
The diff is bigger than I would have liked but a good chunk of it is because I extracted some code from
update_navigation
to individual functions (either out of necessity or to be able to express the algorithm with higher level methods). There isn't actually that much new code.I also updated the documentation of the signals/methods/properties that were affected by this change. Some of the changes are because the behavior changed, others are because the documentation wasn't actually 100% correct from the start.
Fixes NavigationAgents'
is_target_reached
returnsfalse
even withintarget_desired_distance
to thetarget_position
#82560Bugsquad edit:
Fixes The "Target Reached" signal on the NavigationAgent2D node does not reliably trigger when the path desired distance is set above the target desired distance #85247